﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;

namespace Writerous
{
    public partial class frmInsertFiles : Form
    {
        public static uint SEE_MASK_NOCLOSEPROCESS = 0x00000040;
        public static uint SEE_MASK_INVOKEIDLIST = 0x0000000c;
        public static uint SEE_MASK_FLAG_NO_UI = 0x00000400;
        public static int SW_SHOW = 5;

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct SHELLEXECUTEINFO
        {
            public int cbSize;
            public uint fMask;
            public IntPtr hwnd;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpVerb;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpFile;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpParameters;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpDirectory;
            public int nShow;
            public IntPtr hInstApp;
            public IntPtr lpIDList;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpClass;
            public IntPtr hkeyClass;
            public uint dwHotKey;
            public IntPtr hIconMonitorUnion;
            public IntPtr hProcess;
        }

        [DllImport("shell32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);

        public frmInsertFiles()
        {
            InitializeComponent();
            lbFiles.DisplayMember = "Name";
        }

        public FileInfo[] Files
        {
            get
            {
                return lbFiles.Items.ToFileInfoArray();
            }
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            FileInfo file;
            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                string[] supportedExtensions = { ".doc", ".ppt", ".pdf", ".jpg", ".gif", ".png", ".mp3", ".avi", ".mpg" };
                file = new FileInfo(openFileDialog1.FileName);
                if (supportedExtensions.Contains(file.Extension.ToLower()))
                {
                    lbFiles.Items.Add(file);
                }
                else
                {
                    MessageBox.Show("Sorry, this file type '" + file.Extension + "' is not supported", "File type not supported", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (lbFiles.SelectedItems.Count > 0)
            {
                DialogResult delete = MessageBox.Show("Are you sure you want to remove this file?", "Are you sure?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (delete == DialogResult.Yes)
                {
                    lbFiles.Items.Remove(lbFiles.SelectedItem);
                }
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (lbFiles.Items.Count > 0)
            {
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lbFiles.SelectedItems.Count > 0)
            {
                FileInfo n = lbFiles.SelectedItem as FileInfo;
                SHELLEXECUTEINFO shInfo = new SHELLEXECUTEINFO();
                shInfo.lpFile = n.FullName;
                shInfo.fMask = SEE_MASK_INVOKEIDLIST;
                shInfo.lpVerb = "properties";
                shInfo.lpParameters = "";
                shInfo.nShow = SW_SHOW;
                shInfo.cbSize = Marshal.SizeOf(shInfo);
                bool result = ShellExecuteEx(ref shInfo);
                if (!result)
                {
                    Win32Exception ex = new Win32Exception();
                    Console.WriteLine(ex.Message);
                }
            }
        }

        private void lbFiles_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                Point p = new Point(e.X, e.Y);
                lbFiles.SelectedIndex = lbFiles.IndexFromPoint(p);
            }
            propertiesToolStripMenuItem.Enabled = (lbFiles.SelectedItems.Count > 0);
            deleteToolStripMenuItem.Enabled = (lbFiles.SelectedItems.Count > 0);
        }

        private void addToolStripMenuItem_Click(object sender, EventArgs e)
        {
            btnAdd_Click(this, null);
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            btnDelete_Click(this, null);
        }

        private void lbFiles_DoubleClick(object sender, EventArgs e)
        {
            if (lbFiles.SelectedItems.Count > 0)
                propertiesToolStripMenuItem_Click(this, null);
        }
    }

    public static class ExtensionMethods
    {
        public static FileInfo[] ToFileInfoArray(this ListBox.ObjectCollection list)
        {
            List<FileInfo> result = new List<FileInfo>();
            foreach (var item in list)
            {
                result.Add((FileInfo)item);
            }
            return result.ToArray();
        }
    }
}
